﻿using QxFramework.Utilities;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;using UnityEngine.UI;
public class PlayerManager : MonoSingleton<PlayerManager>, IEventListener
{
    public CreatureData Data;
    private Animator Anim;
    private static NextAction CurrentAction; // 暂存行动，使用完后应置空
                                             //public GameObject SceneCamera;
    //玩家的经验值
    private int PlayerExp=2;
    //玩家属性值

    //玩家UI
    private GameObject Hp;
    private GameObject ATK;
    private GameObject Def;


    private void Awake()
    {
        Initiate();
        Hp = GameObject.Find("UI/Player/PlayerHP/HP");
        ATK = GameObject.Find("UI/Player/PlayerAttack/Attack");
        Def = GameObject.Find("UI/Player/PlayerDefence/Defence");
        //if (!SceneCamera) SceneCamera = GameObject.Find("SceneCamera_");
    }

    //void Update()
    //{
    //    if(Input.GetKeyDown(KeyCode.G))
    //    {
    //        SceneCamera.transform.SetParent(GameObject.Find("Map").transform);
    //    }
    //}

    /// <summary>
    /// 初始化方法
    /// </summary>
    public void Initiate()
    {
        if (Data == null) {
            Data = GetComponent<CreatureData>();
            Data.Component = this;
        }        if (Anim == null) Anim = GetComponent<Animator>();

        Data.FlushCoordinate();
        
        Destroy(GameObject.Find("Main_Camera"));
    }
    private void Start()
    {
        if (EventNodeCore.GetInstance())
        {
            EventNodeCore.GetInstance().AttachEventListener(EventDef.PlayerTurn, Instance);
            EventNodeCore.GetInstance().AttachEventListener(EventDef.PlayerMove, Instance);
            EventNodeCore.GetInstance().AttachEventListener(EventDef.PlayerAtk, Instance);
            EventNodeCore.GetInstance().AttachEventListener(EventDef.PlayerItem, Instance);
            EventNodeCore.GetInstance().AttachEventListener(EventDef.PlayerInterAct, Instance);
            EventNodeCore.GetInstance().AttachEventListener(-EventDef.Battle, Instance);
            EventNodeCore.GetInstance().AttachEventListener(EventDef.HpChange, Instance);
            EventNodeCore.GetInstance().AttachEventListener(EventDef.AtkChange, Instance);
            EventNodeCore.GetInstance().AttachEventListener(EventDef.DefChange, Instance);
            EventNodeCore.GetInstance().AttachEventListener(EventDef.ExpChange, Instance);
        }
    }
    private void OnDestroy()
    {
        if (EventNodeCore.GetInstance())
        {
            EventNodeCore.GetInstance().DetachEventListener(EventDef.PlayerTurn, Instance);
            EventNodeCore.GetInstance().DetachEventListener(EventDef.PlayerMove, Instance);
            EventNodeCore.GetInstance().DetachEventListener(EventDef.PlayerAtk, Instance);
            EventNodeCore.GetInstance().DetachEventListener(EventDef.PlayerItem, Instance);
            EventNodeCore.GetInstance().DetachEventListener(EventDef.PlayerInterAct, Instance);
            EventNodeCore.GetInstance().DetachEventListener(-EventDef.Battle, Instance);
            EventNodeCore.GetInstance().DetachEventListener(EventDef.HpChange, Instance);
            EventNodeCore.GetInstance().DetachEventListener(EventDef.AtkChange, Instance);
            EventNodeCore.GetInstance().DetachEventListener(EventDef.DefChange, Instance);
            EventNodeCore.GetInstance().DetachEventListener(EventDef.ExpChange, Instance);
        }
    }

    public bool HandleEvent(int id, object param1, object param2)
    {
        switch (id)
        {
            case EventDef.PlayerTurn: // 玩家行动回合
                Action();
                break;
            case EventDef.PlayerMove: // 收到了移动命令
                MoveSig((DiceData)param1);
                break;
            case EventDef.PlayerAtk: // 收到了攻击命令
                AtkSig((GameObject)param1); // 暂存攻击命令
                break;
            case EventDef.PlayerItem: // 收到了使用道具命令
                // TODO 暂存使用道具命令
                break;
            case EventDef.PlayerInterAct: // 收到了互动命令
                // TODO 暂存互动命令
                break;
            case -EventDef.Battle: //被攻击
                if ((GameObject)param2 == gameObject)
                {
                    Attacked((CreatureData)param1);
                } // 受攻击的是自己
                break;
            case EventDef.HpChange:
                if ((GameObject)param2 == gameObject)
                {
                    Data.HP += (int)param1;
                    Debug.LogWarning(Data.hp + "HP");
                    Hp.GetComponent<Text>().text = Data.HP.ToString();
                    if(Data.HP <= 0)
                    {
                        Dead();
                    }
                } // Hp变动
                break;
            case EventDef.AtkChange:
                if ((GameObject)param2 == gameObject)
                {
                    Debug.LogWarning("ATK"+Data.atk);
                    Data.ATK += (int)param1;
                    ATK.GetComponent<Text>().text = Data.ATK.ToString();
                } // Atk变动
                break;
            case EventDef.DefChange:
                if ((GameObject)param2 == gameObject)
                {
                    Debug.LogWarning("def"+Data.def);
                    Data.DEF += (int)param1;
                    Def.GetComponent<Text>().text = Data.DEF.ToString();
                } // Def变动
                break;
                //收到经验变化信号
            case EventDef.ExpChange:
                Debug.LogWarning("EXP");
                int ExpChange = (int)param1;
                PlayerExp = PlayerExp + ExpChange;
                break;
            default:
                Debug.LogError("该行动注册但没写！" + id + " " + param1 + " " + param2);
                break;
        }
        return false;
    }

    public int EventPriority() { return 0; }

    /// <summary>
    /// 行动
    /// </summary>
    private void Action()
    {
        if (CurrentAction != null)
        {
            RegistAction(1);
            switch (CurrentAction.ActType)
            {
                case EventDef.PlayerMove:
                    MoveAct();
                    break;
                case EventDef.PlayerAtk:
                    Attack1();
                    break;
                // TODO 其他case
                default:
                    Debug.LogError("还没写！");
                    break;
            }
            RegistAction(-1);
        }
        /*
         * 注册行动开始
         * 跳转至各行动
         * 行动注销由具体行动执行
         * 注销时清空CurrentAction
         */
    }
    /// <summary>
    /// 缓存移动信号
    /// </summary>
    /// <param name="target"></param>
    /// <returns></returns>
    private bool MoveSig(DiceData target)
    {
        //Debug.Log("角色缓存移动信号");
        if (CurrentAction == null)
        {
            CurrentAction = new NextAction();
        }
        //Data.FlushCoordinate();
        CurrentAction.ActType = EventDef.PlayerMove;
        CurrentAction.MoveData = RotateBase.MoveToJudge(Data.CoorDinate, target);
        CurrentAction.MoveData.Target = gameObject;
        //Debug.LogError(CurrentAction.MoveData);
        return false;
    }
    /// <summary>
    /// 缓存攻击信号
    /// </summary>
    /// <param name="target"></param>
    /// <returns></returns>
    private bool AtkSig(GameObject target)
    {
        Debug.Log("角色缓存攻击信号");
        if (CurrentAction == null)
        {
            CurrentAction = new NextAction
            {
                MoveData = new MoveData()
            };
        }
        Vector3 facingTo = RotateBase.DirectionJudge(target.GetComponent<CreatureData>().CoorDinate, Data.CoorDinate);

        if (facingTo != Data.Towards)
        {
            CurrentAction.MoveData.Type = 0;
            CurrentAction.MoveData.To = new DiceData() { GroundTowards = facingTo};
            CurrentAction.MoveData.From = Data.CoorDinate;
            CurrentAction.MoveData.Target = this.gameObject;
        } // 需要转向
        else
        {
            CurrentAction.MoveData.Type = 3;
        } // 不用转向
        CurrentAction.ActType = EventDef.PlayerAtk;
        CurrentAction.AttackTarget = target;
        return false;
    }
    /// <summary>
    /// 被攻击
    /// </summary>
    private Vector3 AttackFrom;
    private void Attacked(CreatureData motherfucker)
    {
        AttackFrom = RotateBase.DirectionJudge(motherfucker.CoorDinate, Data.CoorDinate);
        {
            Debug.Log(AttackFrom);
            StartCoroutine(RotateBase.BeAttacked(gameObject, AttackFrom, 0.2f, Attacked2));
        } // 被击中反馈
    }

    private void Attacked2()
    {
        StartCoroutine(Attacked3());
    }

    private IEnumerator Attacked3()
    {
        yield return new WaitForSeconds(0.4f);
        StartCoroutine(RotateBase.FaceTo(gameObject, AttackFrom));
        AttackFrom = Vector3.zero;
    }

    /// <summary>
    /// 移动行动
    /// </summary>
    private void MoveAct()
    {
        //Debug.Log("角色移动， movedata:" + CurrentAction.MoveData);
        StartCoroutine(RotateBase.FaceTo(Data.Towards, CurrentAction.MoveData, Instance.MoveHero)); // 执行转动面向，并传递入移动方法委托 
    }
    /// <summary>
    /// 使角色移动
    /// </summary>
    public void MoveHero()
    {
        switch (CurrentAction.MoveData.Type)
        {
            case 0:
            case 2:
                Anim.SetTrigger("Jump");
                StartCoroutine(RotateBase.Turning(CurrentAction.MoveData, Instance.gameObject, (float)0.4));
                break;
            case 1:
                //Debug.Log("MOVE tarward");
                StartCoroutine(RotateBase.MoveToward(transform.gameObject, CurrentAction.MoveData, (float)0.4));
                break;
            case 3:
                Debug.LogError("移动目标错误！");
                break;
        }
        Data.FlushCoordinate(CurrentAction.MoveData.To);
        CurrentAction = null; // 清空行动数据

    }
    /// <summary>
    /// 攻击的第一阶段，转向
    /// </summary>
    private void Attack1()
    {
        Debug.Log("角色发出攻击");
        if(CurrentAction.MoveData.Type == 0)
        {
            StartCoroutine(RotateBase.FaceTo(Data.Towards, CurrentAction.MoveData, Instance.Attack2));
        } // 要转向的
        else
        {
            Attack2();
        } // 不转向的
    }
    /// <summary>
    /// 攻击的第二阶段，发出攻击,暂时用协程解决。
    /// </summary>
    private void Attack2()
    {
        StartCoroutine(RotateBase.AttackAnim(transform.parent.gameObject, Data.Towards, (float)0.2, Attacking));
    }
    /// <summary>
    /// 发出攻击信号，只由动画调用。
    /// </summary>
    public void Attacking()
    {
        Debug.Log("角色发出攻击信号");
        EventNodeCore.GetInstance().HandleEvent(EventDef.Battle, Data, CurrentAction.AttackTarget);
        CurrentAction = null; // 清空行动数据
    }
    /// <summary>
    /// 死了
    /// </summary>
    public void Dead()
    {
        Debug.LogError("角色死亡，游戏结束！");
        SceneManager.LoadScene("NewCrystal");
    }
    /// <summary>
    /// 注册行动或注销
    /// </summary>
    /// <param name="IsR">1为注册，-1为注销</param>
    private void RegistAction(int IsR)
    {
        EventNodeCore.GetInstance().HandleEvent(EventDef.Action * IsR, null, null);
        //if (IsR < -0.01)
        //{
        //    CurrentAction = null;
        //} // 清空行动数据
    }
    private void OnCollisionEnter(Collision collision)
    {
        if (collision.collider.tag == "Knife")
        {
            Debug.Log("get Knife");
            ObjectPool.GetInstance().Return(collision.collider.gameObject);
        }
    }
    /// <summary>
    /// 角色属性数值获取
    /// </summary>
    //public CreatureData GetPlayerGrowData()
    //{
    //    int Leavel = PlayerExp;
    //    Data.HP=int.Parse(TableAgent.Instance.GetString("Exp",Leavel.ToString(),"Hp"));
    //    Data.ATK = int.Parse(TableAgent.Instance.GetString("Exp",Leavel.ToString(),"Attack"));
    //    Data.DEF= int.Parse(TableAgent.Instance.GetString("Exp",Leavel.ToString(),"Defence"));
    //    return Data;
    //}
}